<template>
  <div>
    <div class="mx-2.5 mb-5">
      <el-form label-width="80px">
        <el-button type="primary" size="mini" class="!ml-2.5" @click="refresh"
          >刷新</el-button
        >
        <el-dropdown
          class="ml-2.5"
          size="mini"
          split-button
          type="success"
          @command="(cmd) => handleSelect(cmd)"
          @click="handleSelect('currentPage')"
        >
          选择(本页)
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="all">全部</el-dropdown-item>
            <el-dropdown-item command="cancelAll">取消全部</el-dropdown-item>
            <el-dropdown-item command="sent">已发送</el-dropdown-item>
            <el-dropdown-item command="unsent">未发送</el-dropdown-item>
            <el-dropdown-item command="read">已阅读</el-dropdown-item>
            <el-dropdown-item command="unread">未阅读</el-dropdown-item>
            <el-dropdown-item command="valid">验证通过</el-dropdown-item>
            <el-dropdown-item command="unknown">未验证</el-dropdown-item>
            <el-dropdown-item command="invalid">验证未通过</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-button
          type="primary"
          size="mini"
          class="!ml-2.5"
          @click="addReceiverVisible = true"
          >{{ $t('email.addRecipient') }}</el-button
        >
        <input
          ref="excelUploadInput"
          class="hidden"
          type="file"
          accept=".xlsx,.xls,.csv,.txt"
          @change="handleUpload"
        />
        <el-dropdown
          class="ml-2.5"
          size="mini"
          split-button
          type="success"
          @click="() => $refs.excelUploadInput.click()"
        >
          导入文件(txt,csv,excel)
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item
              ><el-link
                :underline="false"
                href="/template/receiver_template.csv"
              >
                {{ $t('uploadExcel.downloadTemplate') }}
              </el-link></el-dropdown-item
            >
          </el-dropdown-menu>
        </el-dropdown>
        <el-button
          type="primary"
          size="mini"
          class="!ml-2.5"
          @click="handleExport"
          >导出</el-button
        >
        <el-dropdown
          class="ml-2.5"
          size="mini"
          split-button
          type="danger"
          @command="(cmd) => handleBatchRemove(cmd)"
          @click="handleBatchRemove('selection')"
        >
          批量删除(选中)
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="all">全部</el-dropdown-item>
            <el-dropdown-item command="currentPage">本页</el-dropdown-item>
            <el-dropdown-item command="sent">已发送</el-dropdown-item>
            <el-dropdown-item command="unsent">未发送</el-dropdown-item>
            <el-dropdown-item command="read">已阅读</el-dropdown-item>
            <el-dropdown-item command="unread">未阅读</el-dropdown-item>
            <el-dropdown-item command="valid">验证通过</el-dropdown-item>
            <el-dropdown-item command="unknown">未验证</el-dropdown-item>
            <el-dropdown-item command="invalid">验证未通过</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-dropdown
          class="ml-2.5"
          size="mini"
          split-button
          type="success"
          @command="(cmd) => handleVerifyEmails(cmd)"
          @click="handleVerifyEmails('selection')"
        >
          邮箱真实性验证(选中)
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="all">全部</el-dropdown-item>
            <el-dropdown-item command="currentPage">本页</el-dropdown-item>
            <el-dropdown-item command="valid">验证通过</el-dropdown-item>
            <el-dropdown-item command="unknown">未验证</el-dropdown-item>
            <el-dropdown-item command="invalid">验证未通过</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-dropdown
          class="ml-2.5"
          size="mini"
          split-button
          type="primary"
          @command="(cmd) => handleBatchMoveToBlackList(cmd)"
          @click="handleBatchMoveToBlackList('selection')"
        >
          批量加入黑名单(选中)
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="all">全部</el-dropdown-item>
            <el-dropdown-item command="currentPage">本页</el-dropdown-item>
            <el-dropdown-item command="sent">已发送</el-dropdown-item>
            <el-dropdown-item command="unsent">未发送</el-dropdown-item>
            <el-dropdown-item command="read">已阅读</el-dropdown-item>
            <el-dropdown-item command="unread">未阅读</el-dropdown-item>
            <el-dropdown-item command="valid">验证通过</el-dropdown-item>
            <el-dropdown-item command="unknown">未验证</el-dropdown-item>
            <el-dropdown-item command="invalid">验证未通过</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-button
          type="primary"
          size="mini"
          class="!ml-2.5"
          @click="handleManageBlackList"
          >黑名单</el-button
        >
      </el-form>
    </div>
    <div class="my-2.5 mx-5 py-2.5 px-2.5 border border-solid border-[#e6ebf5]">
      <el-table
        ref="table"
        :data="showList"
        class="w-full"
        height="calc(100vh - 310px)"
        row-key="email"
        @selection-change="handleSelection"
      >
        <el-table-column
          type="selection"
          reserve-selection
          align="center"
        ></el-table-column>
        <el-table-column :label="$t('email.recipient')" align="center">
          <template slot-scope="scope">
            {{ scope.row.email }}
          </template>
        </el-table-column>
        <el-table-column :label="$t('common.name')" align="center">
          <template slot-scope="scope">
            {{ scope.row.name }}
          </template>
        </el-table-column>
        <el-table-column label="是否有效" align="center" width="100px">
          <template slot-scope="scope">
            <span v-if="scope.row.valid === 1" class="text-green-500"
              >有效</span
            >
            <span v-else-if="scope.row.valid === 2" class="text-red-500"
              >无效</span
            >
            <span v-else class="text-gray-500">未验证</span>
          </template>
        </el-table-column>
        <el-table-column label="已发送" align="center" width="70px">
          <template slot-scope="scope">
            <span v-if="scope.row.sendNum" class="text-green-500">是</span>
            <span v-else class="text-red-500">否</span>
          </template>
        </el-table-column>
        <!-- <el-table-column label="已读" align="center" width="70px">
          <template slot-scope="scope">
            <span v-if="scope.row.isRead" class="text-green-500">是</span>
            <span v-else class="text-red-500">否</span>
          </template>
        </el-table-column> -->

        <el-table-column align="center">
          <template slot="header">
            <el-input
              v-model="searchAddressee"
              size="mini"
              clearable
              :placeholder="$t('email.enterSearchAddressee')"
            />
          </template>
          <template slot-scope="scope">
            <el-button
              size="mini"
              plain
              @click="handleEmailRemove(scope.row)"
              >{{ $t('email.remove') }}</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="queryList.length > 0"
        :total="queryList.length"
        :page.sync="pageInfo.page"
        :limit.sync="pageInfo.limit"
        :page-sizes="[10, 20, 30, 50, 100, 200]"
      />
    </div>
    <el-dialog
      title="添加收件人"
      :close-on-click-modal="false"
      width="540px"
      :visible.sync="addReceiverVisible"
      append-to-body
    >
      <el-form
        class="mb-5"
        :model="addReceiverForm"
        ref="addReceiverForm"
        label-width="70px"
      >
        <el-form-item label="邮箱账号" prop="email">
          <el-input v-model="addReceiverForm.email" clearable> </el-input>
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="addReceiverForm.name" clearable> </el-input>
        </el-form-item>
        <!-- <el-form-item label="手机号码" prop="phone">
          <el-input v-model="addReceiverForm.phone" clearable> </el-input>
        </el-form-item> -->
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addReceiverVisible = false">{{
          $t('common.cancel')
        }}</el-button>
        <el-button type="primary" @click="submitAddReceiver">{{
          $t('permission.confirm')
        }}</el-button>
      </span>
    </el-dialog>
    <manage-black-list :show.sync="showManageBlackListVisible" />
  </div>
</template>

<script>
import { getAction, postAction, postLongTimeAction } from '@/api/common'
import XLSX from 'xlsx'
import Pagination from '@/components/Pagination/index.vue'
import { EmailModule } from '@/store/modules/email'
import ManageBlackList from '../manageBlackList.vue'
import request from '@/utils/request'
import languageEncoding from 'detect-file-encoding-and-language'
export default {
  name: 'receiverList',
  components: { Pagination, ManageBlackList },
  props: {
    emailsTemp: '',
    addressee: [],
  },
  inject: ['showProgressDialog'],
  data() {
    return {
      /// //////////////////////////收件列表//////////////////////////////////
      addresseeType: 'pasteInputAddressee',
      addresseeTemp: '',
      searchAddresser: '',
      searchAddressee: '',
      AddresseeLabel: [],
      listOfAuthorizedMailbox: [],
      listOfCustomerMailbox: [],
      listOfCustomerMailboxArray: [],
      importCustomerSelectionRadio: 'byGroup',
      propsCustomer: {
        multiple: true,
        emitPath: false,
        value: 'value',
        label: 'label',
      },
      getCustomerSelectionOptionsUrls: '',
      form: {
        Addressee: [],
      },
      pageInfo: {
        page: 1,
        limit: 100,
      },
      addReceiverVisible: false,
      addReceiverForm: {
        email: '',
        name: '',
        phone: '',
      },
      selection: [],
      showManageBlackListVisible: false,
    }
  },
  created() {
    this.$emit('update:addressee', this.selection)
    this.refresh()
  },
  computed: {
    showList() {
      const start = (this.pageInfo.page - 1) * this.pageInfo.limit
      let end = start + this.pageInfo.limit
      end = Math.min(end, this.queryList.length)
      return this.queryList.slice(start, end)
    },
    queryList() {
      return EmailModule.receivers.filter(
        (data) =>
          !this.searchAddressee ||
          data.email.toLowerCase().includes(this.searchAddressee.toLowerCase())
      )
    },
  },
  methods: {
    refresh() {
      EmailModule.SET_RECEIVERS([...EmailModule.receivers])

      // 禁用是否阅读列
      // if (EmailModule.receivers.length === 0) {
      //   localStorage.setItem(
      //     'latestGetReadEmailsTime',
      //     moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
      //   )
      // } else {
      //   let latestGetReadEmailsTime =
      //     localStorage.getItem('latestGetReadEmailsTime') || '2024-02-26'
      //   postAction(
      //     { time: latestGetReadEmailsTime },
      //     'emailMarketing/getReadEmails'
      //   ).then((res) => {
      //     for (let email of res.data) {
      //       let rec = EmailModule.receivers.find((r) => r.email === email)
      //       if (rec) rec.isRead = true
      //     }
      //     EmailModule.SET_RECEIVERS([...EmailModule.receivers])
      //     localStorage.setItem(
      //       'latestGetReadEmailsTime',
      //       moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
      //     )
      //   })
      // }
    },
    /// //////////////////////////收件列表//////////////////////////////////
    getFilterRows(command) {
      let result = []
      if (command === 'currentPage') {
        result = this.showList
      } else if (command === 'all') {
        result = EmailModule.receivers
      } else if (command === 'cancelAll') {
        result = []
      } else if (command === 'valid') {
        result = EmailModule.receivers.filter((r) => r.valid === 1)
      } else if (command === 'unknown') {
        result = EmailModule.receivers.filter((r) => !r.valid)
      } else if (command === 'invalid') {
        result = EmailModule.receivers.filter((r) => r.valid === 2)
      } else if (command === 'selection') {
        result = this.selection
      } else if (command === 'sent') {
        result = EmailModule.receivers.filter((r) => r.sendNum)
      } else if (command === 'unsent') {
        result = EmailModule.receivers.filter((r) => !r.sendNum)
      } else if (command === 'read') {
        result = EmailModule.receivers.filter((r) => r.isRead)
      } else if (command === 'unread') {
        result = EmailModule.receivers.filter((r) => !r.isRead)
      }

      return result
    },
    handleSelect(command) {
      let rows = this.getFilterRows(command)
      if (command === 'currentPage') {
        this.$refs.table.toggleAllSelection()
      } else if (command === 'all') {
        for (let item of EmailModule.receivers) {
          this.$refs.table.toggleRowSelection(item, true)
        }
      } else if (command === 'cancelAll') {
        this.$refs.table.clearSelection()
      } else {
        for (let item of rows) {
          this.$refs.table.toggleRowSelection(item, true)
        }
      }
    },
    handleSelection(val) {
      this.selection = val
      this.$emit('update:addressee', this.selection)
    },
    handleBatchRemove(cmd) {
      let receivers = EmailModule.receivers
      if (cmd === 'all') {
        receivers = []
      } else {
        let rows = this.getFilterRows(cmd)
        for (let item of rows) {
          receivers.splice(
            receivers.findIndex((i) => i === item),
            1
          )
        }
      }

      EmailModule.SET_RECEIVERS(receivers)
      this.$emit('update:addressee', [])
      this.$refs.table.clearSelection()
      this.$message.success('删除成功')
    },
    batchAddAddress() {
      const addresseeTemp = this.addresseeTemp.trim()

      let filteredArr = this.filterEmails(
        addresseeTemp.split('\n').map((a) => ({ email: a }))
      )
      filteredArr = this.filterEmails(filteredArr).map((m) => m.email)
      if (filteredArr.length === 0) {
        this.$message.warning(this.$t('email.checkEmailIsCorrect'))
        return false
      }

      postAction(filteredArr, 'Customer/BatchGetIdByEmail').then((res) => {
        this.form.Addressee.push(...res.data)
        this.addresseeTemp = ''
      })
    },
    submitAddReceiver() {
      let form = { ...this.addReceiverForm }
      if (!form.email) return this.$message.warning('邮箱不能为空')
      if (!this.$common.checkEmailAddress(form.email))
        return this.$message.warning('邮箱格式错误')
      if (EmailModule.receivers.map((r) => r.email).indexOf(form.email) >= 0)
        return this.$message.warning('邮箱已存在')
      EmailModule.receivers.push(form)
      EmailModule.SET_RECEIVERS(EmailModule.receivers)
      this.$refs.table.toggleRowSelection(form, true)

      this.$message.success('添加成功')
      this.addReceiverVisible = false
      this.$refs.addReceiverForm.resetFields()
    },
    filterEmails(emails) {
      const set = new Set()
      const result = []
      let emptyEmail = 0,
        duplicateEmail = 0,
        invalidEmail = 0
      let duplicateEmails = {},
        invalidEmails = []
      for (let i = 0; i < emails.length; i++) {
        const email = emails[i]
        email.email = email.email.trim()
        if (!email.email) {
          emptyEmail++
          continue
        }
        if (!this.$common.checkEmailAddress(email.email)) {
          invalidEmails.push(email.email)
          invalidEmail++
          continue
        }
        if (
          EmailModule.receivers.map((r) => r.email).indexOf(email.email) >= 0 ||
          set.has(email.email)
        ) {
          if (!duplicateEmails[email.email]) {
            duplicateEmails[email.email] = 1
          } else {
            duplicateEmails[email.email]++
          }
          duplicateEmail++
          continue
        }

        result.push(email)
        set.add(email.email)
      }
      console.log(
        `过滤空邮箱${emptyEmail}个, 非法邮箱${invalidEmail}个,`,
        invalidEmails,
        `, 重复邮箱${duplicateEmail}`,
        duplicateEmails
      )
      return result
    },
    addNewAddressee() {
      const addresseeTemp = this.addresseeTemp.trim()
      // 验证是否为空
      if (addresseeTemp.length === 0) {
        this.$message.warning(this.$t('email.cannotBeEmpty'))
        return false
      }
      // 验证是否邮箱格式
      if (!this.$common.checkEmailAddress(addresseeTemp)) {
        this.$message.warning(this.$t('email.emailIncorrect'))
        return false
      }

      // 验证是否重复
      if (
        EmailModule.receivers.map((r) => r.email).indexOf(addresseeTemp) > -1
      ) {
        this.$message.warning(this.$t('email.emailExists'))
        return false
      }
      postAction({ email: addresseeTemp }, 'Customer/GetIdByEmail').then(
        (res) => {
          if (res.data) {
            this.form.Addressee.push(res.data)
          } else {
            this.form.Addressee.push({
              email: addresseeTemp,
              name: this.$t('common.empty'),
              id: null,
            })
          }
          this.addresseeTemp = ''
        }
      )
    },
    handleEmailRemove(val) {
      EmailModule.receivers.splice(
        EmailModule.receivers.findIndex((i) => i === val),
        1
      )
      EmailModule.SET_RECEIVERS(EmailModule.receivers)
      this.$emit('update:addressee', this.selection)
    },
    handleImportCustomerSelectionRadioChange() {
      this.getCustomerSelectionOptions(this.importCustomerSelectionRadio)
    },
    getCustomerSelectionOptions(types) {
      getAction({}, `Customer/GetCustomerSelectionOptions?type=${types}`).then(
        (res) => {
          this.listOfCustomerMailbox = res.data.listOfCustomerMailbox
          this.listOfCustomerMailbox.forEach((m) => {
            m.children?.forEach((c) => {
              this.listOfCustomerMailboxArray[c.value] = c.email
            })
          })
          console.log(res)
          console.log('errresresresresor types')
        }
      )
    },
    changeCustomerEmailAddresserLable(val) {
      console.log(val)
      this.form.AddresseeLabel =
        val?.map((m) => this.listOfCustomerMailboxArray[m]) ?? []
    },
    async handleUpload(e) {
      const files = e.target.files
      if (!files) return
      const rawFile = files[0] // only use files[0]
      this.$refs['excelUploadInput'].value = ''
      let rows = []
      if (rawFile.name.endsWith('.txt') || rawFile.name.endsWith('.csv')) {
        rows = await this.readTxt(rawFile)
      } else {
        rows = await this.readExcel(rawFile)
      }

      let validEmails = this.filterEmails(rows)
      let receivers = EmailModule.receivers
      for (const item of validEmails) {
        item.id = null
        receivers.push(item)
      }
      EmailModule.SET_RECEIVERS(receivers)
      for (const item of validEmails) {
        this.$refs.table.toggleRowSelection(item, true)
      }
    },
    readTxt(rawFile) {
      const readFileWithEncoding = (file) => {
        return languageEncoding(file).then((fileInfo) => {
          return new Promise((resolve) => {
            const reader = new FileReader()
            reader.onload = (e) => {
              resolve(e.target.result)
            }
            console.log('file encoding: ', fileInfo)
            let encoding = fileInfo.encoding
              ? fileInfo.encoding.toLocaleLowerCase()
              : 'gbk'
            if (fileInfo.confidence.encoding < 0.5) {
              encoding = 'gbk'
            }
            reader.readAsText(file, encoding)
          })
        })
      }

      return readFileWithEncoding(rawFile).then((file) => {
        const result = []
        const lines =
          file.indexOf('\r\n') > -1 ? file.split('\r\n') : file.split('\n')
        for (let i = 1; i < lines.length; i++) {
          if (!lines[i]) continue

          const chunks = lines[i].split(',')
          result.push({
            email: chunks[0],
            name: chunks[1],
          })
        }

        return result
      })
    },
    readExcel(rawFile) {
      const reader = new FileReader()
      return new Promise((resolve) => {
        reader.onload = (e) => {
          const data = e.target.result
          const workbook = XLSX.read(data, { type: 'array' })
          const firstSheetName = workbook.SheetNames[0]
          const worksheet = workbook.Sheets[firstSheetName]
          const results = XLSX.utils.sheet_to_json(worksheet, {
            header: ['email', 'name'],
          })
          resolve(results.slice(1))
        }
        reader.readAsArrayBuffer(rawFile)
      })
    },
    handleVerifyEmails(cmd) {
      let action = this.verifyEmailsByServer
      if (this.$store.state.oem.id === 9) {
        if (!this.$common.IsInExe()) {
          this.$alert(
            '使用此功能请在客户端打开！<br>(如果已在客户端，请点击右上角刷新本页面)',
            '提示',
            {
              dangerouslyUseHTMLString: true,
            }
          )
          return
        }
        action = this.verifyEmailsByClient
      }
      let rows = this.getFilterRows(cmd)

      if (rows.length === 0) {
        this.$message.warning('请先选择收件人')
        return
      }

      const data = []
      const addresses = [...rows]
      const batch = this.$store.state.oem.id === 9 ? 20 : 50
      for (let i = 0; i < addresses.length / batch; i++) {
        const start = i * batch
        data.push({
          chunk: addresses.slice(start, start + batch),
        })
      }
      const uploadItems = [{ name: '验证邮箱批次', action, data }]
      this.showProgressDialog(
        uploadItems,
        [],
        () => {
          this.refresh()
        },
        {
          title: `分批次验证邮箱(每批次验证${batch}个邮箱)`,
          autoClose: true,
          autoStart: true,
          delayTime: 200,
        }
      )
    },
    verifyEmailsByServer({ item, message, index }) {
      postLongTimeAction(
        { email: item.chunk.map((m) => m.email) },
        'EmailVerify/Verify'
      ).then(({ data }) => {
        for (const key in data) {
          const email = EmailModule.receivers.find((m) => m.email === key)
          if (email) {
            email.valid = data[key] ? 1 : 2
          }
        }
        // this.form.Addressee = [...this.form.Addressee]
        message.success(`第${index + 1}批邮箱验证完成`)
      })
    },
    verifyEmailsByClient({ item, message, index }) {
      this.$common.ExeInvoke((f) => {
        VUE.$on('VerifyEmail', (data) => {
          for (const key in data) {
            const email = EmailModule.receivers.find((m) => m.email === key)
            if (email) {
              email.valid = data[key] ? 1 : 2
            }
          }

          message.success(`第${index + 1}批邮箱验证完成`)
          VUE.$off('VerifyEmail')
        })
        f.VerifyEmails(item.chunk.map((m) => m.email))
      })
    },
    handleExport() {
      let receivers = this.selection
      if (receivers.length === 0)
        return this.$message.warning('请勾选需要导出的数据')

      let str = '邮箱,名称,手机号\n'
      receivers.forEach((item) => {
        str += item.email + ',' + item.name + ',' + item.phone + '\n'
      })
      const export_blob = new Blob([str])
      const save_link = document.createElement('a')
      save_link.href = window.URL.createObjectURL(export_blob)
      save_link.download = '导出收件列表.csv'
      save_link.click()
    },
    randomSelect(cmd) {
      this.$refs.table.clearSelection()
      for (let row of this.getFilterRows(cmd)) {
        let checked = Math.random() > 0.5
        if (checked) this.$refs.table.toggleRowSelection(row, true)
      }
    },
    handleManageBlackList() {
      this.showManageBlackListVisible = true
    },
    handleBatchMoveToBlackList(cmd) {
      const action = ({ item, message, index }) => {
        postAction({ email: item.email }, 'emailBlackList/create').then(
          (res) => {
            message.success(`邮箱${item.email}移入黑名单[${res.message}]`)
          }
        )
      }
      let rows = this.getFilterRows(cmd)

      if (rows.length === 0) {
        this.$message.warning('请先选择收件人')
        return
      }

      const data = rows
      const uploadItems = [{ name: '邮箱', action, data }]
      this.showProgressDialog(
        uploadItems,
        [],
        () => {
          this.refresh()
        },
        {
          title: '批量加入黑名单',
          autoClose: true,
          autoStart: true,
          delayTime: 200,
        }
      )
    },
  },
}
</script>

<style scoped></style>
